import sys
import json
import random
import os
from termcolor import colored
from lib.stardict import DictCsv
from config import Config


ROOT = os.path.join(Config.ROOT, 'lib')
json_loc = os.path.join(ROOT, 'voc.json')
csv_loc = os.path.join(ROOT, 'ecdict.csv')


def is_phrase(chi):
    if chi[0] == 'a' or chi[0] == 'v' or chi[0] == 'n':
        return False
    else:
        return True


def print_err(*args, **kwargs):
    print(colored(*args, 'red'), file=sys.stderr, **kwargs)


def print_info(*args, **kwargs):
    print(colored(*args, 'yellow'), **kwargs)


def input_info(*args):
    return input(colored(*args, 'yellow'))


def cal_pri(word, review_times):
    if word[2] == 0:
        return 10
    return (word[3] * 10 + review_times) / word[2]  # (wrong_times * 10 + total_review_times) / word_review_times


class Voc:
    def __init__(self):
        with open(json_loc, mode='r') as f:
            v = json.load(f)
        self.review_times = v['review_times']
        self.vocabulary = v['vocabulary']
        self.csv = DictCsv(csv_loc)
        self.all_num = len(self.vocabulary)
        self.phrase_num = 0
        self.word_num = 0
        self.top = -1
        self.done = False
        for i in range(0, self.all_num):
            if is_phrase(self.vocabulary[i][1]):
                self.phrase_num += 1
            else:
                self.word_num += 1

    def save(self):
        with open(json_loc, mode='w') as f:
            json.dump({'review_times': self.review_times,
                       'vocabulary': self.vocabulary
                       }, f)

    def search(self, eng):
        for i in range(0, len(self.vocabulary)):
            if self.vocabulary[i][0] == eng:
                return i
        return -1

    def quick_sort(self, pri_list, lo, hi):
        if lo >= hi:
            return
        pivot = pri_list[lo]
        voc_pivot = self.vocabulary[lo]
        i = lo
        j = hi
        while i < j:
            while pri_list[j] <= pivot and i < j:
                j -= 1
            pri_list[i] = pri_list[j]
            self.vocabulary[i] = self.vocabulary[j]
            while pri_list[i] > pivot and i < j:
                i += 1
            pri_list[j] = pri_list[i]
            self.vocabulary[j] = self.vocabulary[i]
        pri_list[i] = pivot
        self.vocabulary[i] = voc_pivot
        self.quick_sort(pri_list, lo, i - 1)
        self.quick_sort(pri_list, i + 1, hi)

    def permute(self):
        voc_len = len(self.vocabulary)
        for i in range(0, voc_len):
            swap = random.randrange(i, voc_len)
            tmp = self.vocabulary[swap]
            self.vocabulary[swap] = self.vocabulary[i]
            self.vocabulary[i] = tmp

    def append(self, eng, chi):
        if is_phrase(chi):
            self.phrase_num += 1
        else:
            self.word_num += 1
        self.all_num += 1
        self.vocabulary.append([eng, chi, 0, 0])

    def delete(self, now):
        if is_phrase(self.vocabulary[now][1]):
            self.phrase_num -= 1
        else:
            self.word_num -= 1
        self.all_num -= 1
        self.vocabulary.pop(now)

    def query_csv(self, word):
        ret = ''
        query = self.csv.query(word)
        if query:
            if query['phonetic'] != '':
                ret += '[' + query['phonetic'] + ']' + '\n'
            if query['definition'] != '':
                ret += query['definition'] + '\n'
            if query['translation'] != '':
                ret += query['translation'] + '\n'
            if query['exchange'] != "":
                ret += query['exchange'] + '\n'
            ret += '\n'
        return ret

    def voc_info(self):
        return "{0} records, {1} words, {2} phrases, {3} times review".format(self.all_num,
                                                                              self.word_num,
                                                                              self.phrase_num,
                                                                              self.review_times)

    def word_info(self, no):
        return "{0:30}{3}/{2}:{4} {1}".format(self.vocabulary[no][0],
                                              self.vocabulary[no][1],
                                              self.vocabulary[no][2],
                                              self.vocabulary[no][3],
                                              cal_pri(self.vocabulary[no], self.review_times))
